package com.dc.base.ui.activity

import android.app.Activity
import android.os.Bundle
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import com.dc.base.utils.ActivityManager
import com.dc.base.utils.notNull
import com.dc.base.vm.BaseViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.lang.reflect.ParameterizedType

abstract class BaseVmActivity<VM : BaseViewModel> : AppCompatActivity() {

    protected lateinit var mViewModel: VM

    protected lateinit var mActivity: Activity

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        initDataBind().notNull({
            setContentView(it)
        }, {
            setContentView(layoutId())
        })
        mActivity = this
        ActivityManager.addActivity(this)
        mViewModel = createViewModel()
        initView()
        initData()
        createObserver()
        registerUiLoadingChange()
    }

    /**
     * 供子类初始化DataBinding操作
     */
    protected open fun initDataBind(): View? {
        return null
    }

    /**
     * 没有DataBinding/ViewBinding的布局id
     */
    protected abstract fun layoutId(): Int

    protected abstract fun initView()

    protected abstract fun initData()

    /**
     * 创建LiveData数据观察者
     */
    protected open fun createObserver() {
    }

    /**
     * 耗时任务处理
     */
    protected fun <T> launch(
        block: suspend () -> T,
        onSuccess: (T) -> Unit = {},
        onError: (Throwable) -> Unit ={}
    ) = lifecycleScope.launch {
        runCatching {
            withContext(Dispatchers.IO) {
                block()
            }
        }.onSuccess {
            onSuccess(it)
        }.onFailure {
            onError(it)
        }
    }

    private fun registerUiLoadingChange() {
        mViewModel.UiLoadingChange().showLoadingDialog.observe(this, Observer {
            showLoading(it)
        })

        mViewModel.UiLoadingChange().dismissLoadingDialog.observe(this, Observer {
            dismissLoading()
        })
    }

    protected open fun showLoading(message: String = "请求网络中...") {
    }

    protected open fun dismissLoading() {
    }

    override fun onDestroy() {
        super.onDestroy()
        ActivityManager.removeActivity(this)
    }

    private fun createViewModel(): VM {
        val type = javaClass.genericSuperclass as ParameterizedType
        val cls = type.actualTypeArguments[0] as Class<VM>
        return ViewModelProvider(viewModelStore, defaultViewModelProviderFactory)[cls]
    }
}